
using Ebusiness_EntityFrameWork.DBContext;
using Mic.Identity.Model;
using Mic.Identity.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Security;

namespace Mic.Identity
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            var xx = new Lazy<int>(() => 1, true);
            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            //微软Identity数据库上下文
            builder.Services.AddDbContext<AppDbContext>(options =>
                   options.UseMySql("server=127.0.0.1;port=3306;database=AspNetCore_ProductImage_Identity;uid=root;pwd=123456",
                        //指定程序集目录
                        new MySqlServerVersion(new Version(5, 7, 29)))
               );

            builder.Services.AddTransient<ILazyTestService, LazyTestService>();

            //builder.Services.ConfigureApplicationCookie(
            //    opts =>
            //    {
            //        //opts.LoginPath = "/Account/Login";
            //        //设置Cookie名称
            //        opts.Cookie.Name = "zdf.Identity.Application";
            //        //设置Cookie超时时间
            //        opts.ExpireTimeSpan = TimeSpan.FromMinutes(20);
            //        //设置滑动时间
            //        opts.SlidingExpiration = true;
            //    }
            //);
            //微软自带身份认证
            //AddIdentity方法的参数类型指定AppUser类和IdentityRole类
            //AddEntityFrameworkStores方法指定Identity使用EF Core作为存储和项目中使用AppIdentityContext作为DB Context
            builder.Services.AddIdentity<Microsoft.AspNetCore.Identity.IdentityUser, Microsoft.AspNetCore.Identity.IdentityRole>()
         .AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders();
            #region
            {
                //注册授权处理器
                //builder.Services.AddSingleton<IAuthorizationHandler, UserPermissionAuthodrizationHandler>();
                builder.Services.AddSingleton<IAuthorizationHandler>(procider => {
                    var dbContextFactory = procider.GetRequiredService<IServiceScopeFactory>();
                    return new UserPermissionAuthodrizationHandler(dbContextFactory);
                });
                //配置授授权策略
                List<PermissionDefine> permissionDefines = PermissionDefineProvider.GetPermissionDefine();
                builder.Services.AddAuthorization(option =>
                {
                    //IServiceProvider serviceProvider = builder.Services.BuildServiceProvider();
                    //AppDbContext mysqlDBContext = serviceProvider.GetRequiredService<AppDbContext>();
                    foreach (var item in permissionDefines)
                    {
                        ////使用自定义授权策略
                        option.AddPolicy(item.PermissionName, x =>
                        {
                            ////添加自定义声明
                            x.AddRequirements(new UserPermissionAuthorizationRequirement(item.PermissionName));
                        });
                        //将策略自定义策略添加到数据库
                        //Permission permission = new Permission();
                        //permission.PermissionName = item.PermissionName;
                        //permission.PermissionType = item.PermissionType;
                        //permission.PermissionValue = item.PermissionValue;
                        //var data = mysqlDBContext.permissions.Where(x => x.PermissionName == item.PermissionName && x.PermissionType == item.PermissionType).FirstOrDefault();
                        //if (data == null)
                        //    mysqlDBContext.Add(permission);
                    }
                    //mysqlDBContext.SaveChanges();
                });
            }
            builder.Services.AddAuthorization();
            #endregion
            var app = builder.Build();
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.Use(next =>
            {
                return async x =>
                {
                    // 2、给下一个中间件
                    await next(x);
                    var xw = x.Response.StatusCode;
                    bool? bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                };
            });
            app.UseAuthentication();
            app.Use(next =>
            {
                return async x =>
                {
                    // 2、给下一个中间件
                    await next(x);
                    var xw = x.Response.StatusCode;
                    bool? bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                };
            });
            app.UseAuthorization();
            app.Use(next =>
            {
                return async x =>
                {
                    bool bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                    // 2、给下一个中间件
                    await next(x);
                };
            });

            app.MapControllers();

            app.Run();
        }
    }
}
